﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ActiveStory.DataManager.LinkMapData;
using ActiveStory.DataManager;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Media;

namespace ActiveStory
{
    public class LinkMapView
    {
        private const float imageWidthScale = 0.3f;
        private const float imageHeightScale = 0.3f;
        private const int buttonWidth = 100;
        private const int buttonHeight = 30;
        private const int horizontalPageSpacing = 50;
        private const int verticalPageSpacing = 50;
        private const int horizontalButtonSpacing = 25;
        private const int verticalButtonSpacing = 10;
        private const int horizontalLineOffset = 10;
        public Dictionary<int, LinkMapPageElement> LinkMapPageList { get; private set; }
        public void LoadProject(ActiveStoryProject inputProject)
        {
            LinkMapPageList = new Dictionary<int, LinkMapPageElement>();
            foreach (ActiveStoryPageMetadata item in inputProject.PageMetadataList)
            {
                LinkMapPageList.Add(item.PageNumber, new LinkMapPageElement(item));
            }
        }

        public void RenderView(InkCanvas inputCanvas)
        {
            Point currentPoint = new Point(10, 10);
            double maxHeight = 0;
            foreach (LinkMapPageElement item in LinkMapPageList.Values)
            {
                Image pageImage = new Image { Source = new BitmapImage(new Uri(item.PageMetadata.TempThumbnailPath)) };  //@"pack://application:,,,/ActiveStoryEnhanced;component/Content/BlankPage.png", UriKind.Absolute)) };
                pageImage.Width = pageImage.Source.Width * imageWidthScale;
                pageImage.Height = pageImage.Source.Height * imageHeightScale;
                inputCanvas.Children.Add(pageImage);
                item.UiElements.Add(pageImage);
                InkCanvas.SetLeft(pageImage, currentPoint.X);
                InkCanvas.SetTop(pageImage, currentPoint.Y);
                Point basePoint = new Point(currentPoint.X, currentPoint.Y);
                currentPoint.X = currentPoint.X + horizontalButtonSpacing;
                currentPoint.Y = currentPoint.Y + pageImage.Height + verticalButtonSpacing;
                foreach (KeyValuePair<int, int> buttonItem in item.Page.ButtonToPageMap)
                {
                    Button tempButton = new Button { Content = buttonItem.Key.ToString(), Width = buttonWidth, Height = buttonHeight };
                    inputCanvas.Children.Add(tempButton);
                    item.UiElements.Add(tempButton);
                    InkCanvas.SetLeft(tempButton, currentPoint.X);
                    InkCanvas.SetTop(tempButton, currentPoint.Y);
                    Line connectorLine = new Line();
                    connectorLine.X1 = InkCanvas.GetLeft(pageImage) + horizontalLineOffset;
                    connectorLine.Y1 = InkCanvas.GetTop(pageImage) + pageImage.Height;
                    connectorLine.X2 = currentPoint.X - horizontalButtonSpacing + horizontalLineOffset;
                    connectorLine.Y2 = tempButton.Height / 2 + currentPoint.Y;
                    connectorLine.Stroke = Brushes.Black;
                    inputCanvas.Children.Add(connectorLine);
                    connectorLine = new Line();
                    connectorLine.X1 = currentPoint.X - horizontalButtonSpacing + horizontalLineOffset;
                    connectorLine.Y1 = connectorLine.Y2 = tempButton.Height / 2 + currentPoint.Y;
                    connectorLine.X2 = currentPoint.X;
                    connectorLine.Stroke = Brushes.Black;
                    inputCanvas.Children.Add(connectorLine);
                    currentPoint.Y = currentPoint.Y + tempButton.Height + verticalButtonSpacing;
                }

                if (pageImage.Width < (horizontalButtonSpacing + buttonWidth))
                    currentPoint.X = basePoint.X + pageImage.Width + (buttonWidth + horizontalButtonSpacing - pageImage.Width) + horizontalPageSpacing;
                else
                    currentPoint.X = basePoint.X + pageImage.Width + horizontalPageSpacing;
                item.BoundingBox = new Rect(basePoint.X, basePoint.Y, currentPoint.X - basePoint.X - horizontalPageSpacing, currentPoint.Y);

                if (currentPoint.Y > maxHeight)
                    maxHeight = currentPoint.Y;
                currentPoint.Y = basePoint.Y;       // TODO: change this so that it wraps when it gets to the end of the visible area.
            }

            //inputCanvas.Height = maxHeight;
            //inputCanvas.Width = currentPoint.X - horizontalPageSpacing;

            foreach (LinkMapPageElement item in LinkMapPageList.Values)
            {
                Rectangle r = new Rectangle();
                inputCanvas.Children.Add(r);
                r.Width = item.BoundingBox.Width;
                r.Height = item.BoundingBox.Height;
                InkCanvas.SetLeft(r, item.BoundingBox.X);
                InkCanvas.SetTop(r, item.BoundingBox.Y);
                r.Stroke = Brushes.Red;
            }

            currentPoint = new Point(10, 10);
            foreach (LinkMapPageElement item in LinkMapPageList.Values)
            {
                foreach (UIElement element in item.UiElements)
                {
                    if (element.GetType() != typeof(Button))
                        continue;
                    Button tempButton = (Button)element;
                    List<UIElement> targetsElements = LinkMapPageList[item.Page.ButtonToPageMap[int.Parse(tempButton.Content.ToString())]].UiElements;
                    double middleX = 0, middleY = 0;
                    foreach (UIElement targetElement in targetsElements)
                    {
                        if (targetElement.GetType() != typeof(Image))
                            continue;
                        Image tempImage = (Image)targetElement;
                        middleX = InkCanvas.GetLeft(targetElement) + (tempImage.Width / 2);
                        middleY = (InkCanvas.GetTop(targetElement) + (tempImage.Height) / 2);
                        break;
                    }
                    Line connectorLine = new Line();
                    connectorLine.X1 = InkCanvas.GetLeft(tempButton) + (tempButton.Width / 2);
                    connectorLine.Y1 = InkCanvas.GetTop(tempButton) + (tempButton.Height / 2);
                    connectorLine.X2 = middleX;
                    connectorLine.Y2 = middleY;
                    //Canvas.SetZIndex(connectorLine, -1);
                    connectorLine.Stroke = Brushes.Blue;
                    inputCanvas.Children.Add(connectorLine);
                }
            }
        }
    }
}
